package com.base.myproject.client.HR.holiday;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import com.base.myproject.client.busi.BaseStore;
import com.base.myproject.client.busi.BO.BusiObject;
import com.base.myproject.client.jdbc.DataSet;
import com.base.myproject.client.jdbc.StoreInfo;
import com.base.myproject.client.tools.CommandSyncContainer;
import com.base.myproject.client.tools.CommandSyncReturnObject;
import com.base.myproject.client.tools.CommandSyncsql;
import com.base.myproject.client.tools.GreetingService;
import com.base.myproject.client.tools.GreetingServiceAsync;
import com.base.myproject.client.ui.BaseGrid;
import com.base.myproject.client.ui.BaseJDBCPanel;
import com.base.myproject.client.ui.celleditor.BaseComboBoxForm;
import com.extjs.gxt.ui.client.GXT;
import com.extjs.gxt.ui.client.data.BaseModelData;
import com.extjs.gxt.ui.client.data.ModelType;
import com.extjs.gxt.ui.client.event.BaseEvent;
import com.extjs.gxt.ui.client.event.Events;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.event.MessageBoxEvent;
import com.extjs.gxt.ui.client.widget.HorizontalPanel;
import com.extjs.gxt.ui.client.widget.Info;
import com.extjs.gxt.ui.client.widget.Label;
import com.extjs.gxt.ui.client.widget.MessageBox;
import com.extjs.gxt.ui.client.widget.VerticalPanel;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.extjs.gxt.ui.client.widget.form.DateField;
import com.extjs.gxt.ui.client.widget.form.FieldSet;
import com.extjs.gxt.ui.client.widget.form.LabelField;
import com.extjs.gxt.ui.client.widget.form.TextField;
import com.extjs.gxt.ui.client.widget.grid.ColumnConfig;
import com.extjs.gxt.ui.client.widget.grid.ColumnModel;
import com.extjs.gxt.ui.client.widget.layout.FitLayout;
import com.google.gwt.core.client.GWT;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.user.client.rpc.AsyncCallback;

public class VacationManagerPayment extends BaseJDBCPanel{
	
	private Button btnQuery = null;
	private DateField startDate = null;
	private DateField happenDate = null;
	private DateField endDate = null;
	private BaseComboBoxForm<BaseModelData> bcb2= null;  
	private BaseStore<BusiObject> store = null;
	private BaseGrid<BusiObject> grid=null;
	private Button pay = new Button("生成假期扣款");
	
	Label lab = new Label("假期类型：");       //添加一个宿舍号标签
	TextField<String> tx = new TextField<String> ();   //定义一个文本框输入查询条件
	
	public VacationManagerPayment(){
		init();
	}
	
	public void init(){
		addSalaryItemToMap();
		registerMainStore(store);
		initWidget();
	}
	
	private void initWidget(){
		btnQuery = new Button("查询");
		startDate = new DateField();                
		endDate = new DateField(); 
		happenDate = new DateField(); 
		
		startDate.getPropertyEditor().setFormat(DateTimeFormat.getFormat("yyyy-MM-dd"));  
		startDate.setWidth(110);
		endDate.getPropertyEditor().setFormat(DateTimeFormat.getFormat("yyyy-MM-dd"));  
		endDate.setWidth(110);
		happenDate.getPropertyEditor().setFormat(DateTimeFormat.getFormat("yyyy-MM-dd"));  
		happenDate.setWidth(110);
		
		bcb2 = new BaseComboBoxForm<BaseModelData>("HolsCode", "HolsName", "hr_Attendance_holsType", " where 1=1", true);
		
		costBox.setButtons("");
		costBox.setButtons(MessageBox.YESNO);  
		costBox.setIcon(MessageBox.QUESTION);  
		costBox.setTitle("是否生成数据？");  
		costBox.addCallback(new Listener<MessageBoxEvent> (){
			@Override
			public void handleEvent(MessageBoxEvent be) {
				if(be.getButtonClicked().getText().equals(GXT.MESSAGES.messageBox_yes())){
					sqlList.add(getDeleteSql());
					cutPayment();
				}
			}
		});  
		costBox.setMessage("该生成扣款的开始日期已经有扣款数据，是否重新生成？");  
		
		initInnerToolBar();
	}
	
	private void initInnerToolBar(){
		HorizontalPanel hp1 = new HorizontalPanel();
		HorizontalPanel hp4 = new HorizontalPanel();
		VerticalPanel vpanel = new VerticalPanel();
		
		FieldSet fs = new FieldSet();
		fs.setHeading("操作");
		hp1.add(new LabelField("日期从："));
		hp1.add(startDate);
		hp1.add(new LabelField("到："));
		hp1.add(endDate);
		
		Label lab2 = new Label("假期类型："); 
		hp1.add(lab2);
		hp1.add(bcb2);
		bcb2.setWidth(120);
		hp1.add(btnQuery);
		hp1.add(new LabelField("发生日期："));
		hp1.add(happenDate);
		hp1.add(pay);
		
		fs.add(hp1);
		hp4.setSpacing(3);
		vpanel.add(fs);
		vpanel.add(hp4);

		btnQuery.addListener(Events.Select, getListener());
		pay.addListener(Events.Select, getListener());
		
		vpanel.setSpacing(3);
		
		vpanel.add(createGrid());
    	this.setLayout(new FitLayout());
		this.add(vpanel);
	}
	
	BaseStore<BusiObject> getGroupStore() {
		if (store == null) {
			createGroupStore();
		}
		return store;
	}

	BaseStore<BusiObject> createGroupStore() {
		ModelType type_m = new ModelType();
		type_m.setRoot("records");
		type_m.setRecordName("record");
		type_m.setTotalName("totle");
		type_m.addField("bcode");
		type_m.getField("bcode").setType(String.class);
		type_m.addField("others");
		type_m.getField("others").setType(String.class);
		type_m.addField("amount");
		type_m.getField("amount").setType(Double.class);
		type_m.addField("adddate");
		type_m.getField("adddate").setType(Date.class);
		
		StoreInfo info = new StoreInfo();
		info.setTablename("hr_salary_ext");
		info.setKeyname(new String[] { "icode" });
		info.setSql("select * from hr_salary_ext where 1=2");// 初始化的时候只显示当前月份的数据

		store = new BaseStore<BusiObject>(type_m, info);
		return store;
	}
	
	private BaseGrid<BusiObject> createGrid(){
		List<ColumnConfig> columns = new ArrayList<ColumnConfig>();  

		ColumnConfig C2 = new ColumnConfig("bcode","雇佣编号",120);
		BaseComboBoxForm<BusiObject> employno = new BaseComboBoxForm<BusiObject>("bcode","employno","bcode_job"," where employstatus = '在职'",true); 
		C2.setRenderer(employno);
		columns.add(C2);
		
		ColumnConfig C3 = new ColumnConfig("amount", "扣款金额", 120);
		columns.add(C3);
		
		ColumnConfig C4 = new ColumnConfig("others", "请假类型", 120);
		BaseComboBoxForm<BaseModelData> bcb2 = new BaseComboBoxForm<BaseModelData>("batchNo", "batchName", "hr_Attendance_WorkBatch", " where depCode = '00'", true);
		C4.setRenderer(bcb2);
		columns.add(C4);
		
		ColumnConfig C5 = new ColumnConfig("adddate", "发生日期", 120);
		C5.setDateTimeFormat(DateTimeFormat.getFormat("yy-MM-dd"));
		columns.add(C5);
		
		ColumnModel cm = new ColumnModel(columns);
		
	   grid = new BaseGrid<BusiObject>(getGroupStore(), cm, false, false);  
	   grid.setBorders(true);  
	   grid.getView().setShowDirtyCells(false);
	   grid.setSize(920,350);
	   return grid ;
	}
	
	int sync = 0;
	Listener<BaseEvent> defaultlistener;
	MessageBox boxysn = new MessageBox();
	MessageBox costBox = new MessageBox();
	
	String startDateRawValue = "";
	String endDateRawValue = "";
	String happenDateRawValue = "";
	String holidayCode = "";
	List<String> sqlList = new ArrayList<String>();;
	
	Listener<BaseEvent> getListener() {
		if (defaultlistener != null) {
			return defaultlistener;
		}

		defaultlistener = new Listener<BaseEvent>() {
			public void handleEvent(BaseEvent be) {
				sync++;
				try {
					if (sync == 1) {
						if (be.getType() == Events.Select) {
							sqlList.clear();
							holidayCode = "";
							startDateRawValue = startDate.getRawValue();
							endDateRawValue = endDate.getRawValue();
							happenDateRawValue = happenDate.getRawValue().equals("") ? startDateRawValue : happenDate.getRawValue();
							
							if (startDateRawValue.equals("") && endDateRawValue.equals("")) {
								MessageBox.alert("提示", "请填写正确的时间段，谢谢", null);
								return;
							}
							
							if (!bcb2.getRawValue().equals("")) {
						    	holidayCode = bcb2.getValueCode();
						    }
							
							String sql = getSearchSql();
							
						    if(be.getSource().equals(btnQuery)) {
							    store.getStoreinfo().setSql(sql);
							    store.reload();
						    } else {
								GreetingServiceAsync greetingService = GWT.create(com.base.myproject.client.tools.GreetingService.class);
								greetingService.getDataSet(sql,new AsyncCallback<DataSet>() {
									@Override
									public void onFailure(Throwable caught) {
										
									}

									@Override
									public void onSuccess(DataSet result) {
										if (result.getRowCount() > 0) {
											costBox.show();
										} else {
											cutPayment();
										}
									}
								});
						    }
						}
					}
				}
				 finally {
					sync--;
				}
			}
		};
		return defaultlistener;
	}
	
	private String getSearchSql() {
		StringBuilder searchSql = new StringBuilder();
		searchSql.append("select * from hr_salary_ext where code = 'D14' and maketype = '系统生成' and adddate >= '");
		searchSql.append(startDateRawValue);
		searchSql.append("' and adddate <= '");
		searchSql.append(endDateRawValue);
		searchSql.append("'");

		if (!holidayCode.equals("")) {
			holidayCode = bcb2.getValueCode();
			searchSql.append(" and others = '");
			searchSql.append(holidayCode);
			searchSql.append("'");
		}
		
		return searchSql.toString();
	}
	
	private String getDeleteSql() {
		StringBuilder deleteSql = new StringBuilder();
		deleteSql.append("delete hr_salary_ext where code = 'D14' and maketype = '系统生成' and adddate >= '");
		deleteSql.append(startDateRawValue);
		deleteSql.append("' and adddate <= '");
		deleteSql.append(endDateRawValue);
		deleteSql.append("'");

		if (!holidayCode.equals("")) {
			holidayCode = bcb2.getValueCode();
			deleteSql.append(" and others = '");
			deleteSql.append(holidayCode);
			deleteSql.append("'");
		}
		
		return deleteSql.toString();
	}
	
	private Map<String, String> deductionSalaryMap;
	private static VacationConverter converter = VacationConverter.getConverter();
	
	private void cutPayment() {
		deductionSalaryMap = new HashMap<String, String>();
		
		String getDeductionSalarySql = "select deductionSalary, holidayCode from hr_Attendance_vacationManagement where 1=1 and isnull(rtrim(deductionSalary),'') != ''";
		
		if (!holidayCode.equals("")) {
			getDeductionSalarySql += " and holidayCode = '" + holidayCode + "'";
		}
		
		final GreetingServiceAsync greetingService = GWT
				.create(com.base.myproject.client.tools.GreetingService.class);
		greetingService.getDataSet(getDeductionSalarySql, new AsyncCallback<DataSet>() {
			@Override
			public void onFailure(Throwable caught) {
			}

			@Override
			public void onSuccess(DataSet result) {
				if (result.getRowCount() == 0) {
					MessageBox.alert("提示", "没有相应的扣款条件，请重新选择或者在填写完整的扣款条件，谢谢", null);
					return;
				}
				
				for (int i=0; i<result.getRowCount(); i++) {
					deductionSalaryMap.put(result.getValue(i, "holidayCode"), result.getValue(i, "deductionSalary"));
				}
				
				String insertExtSql = "insert hr_salary_ext(bcode, code, adddate, others, amount, maketype) select * from (";
				String searchSql = "";
				
				Iterator<String> iterator = deductionSalaryMap.keySet().iterator();
				String holidayCode = "";
				while (iterator.hasNext()) {
					holidayCode = iterator.next();
					searchSql = getCutPaymentWithVacationDatesSql(holidayCode);
					insertExtSql += searchSql + " union all ";
				}
				
				insertExtSql = insertExtSql.substring(0, insertExtSql.length() - 11) + ") as a where amount is not null";
				sqlList.add(insertExtSql);
				commandSql(sqlList);
			}
		});
	}
	
	private String getCutPaymentWithVacationDatesSql(String holidayCode) {
		StringBuilder cutPaymentSql = new StringBuilder();
		cutPaymentSql.append("select bcode, 'D14' as c, '");
		cutPaymentSql.append(happenDateRawValue);
		cutPaymentSql.append("' as date,'");
		cutPaymentSql.append(holidayCode);
		cutPaymentSql.append("' as code, case ");
		cutPaymentSql.append(converter.convert(deductionSalaryMap.get(holidayCode)));
		if (holidayCode.equals("EL") || holidayCode.equals("SL")) {
			cutPaymentSql.append(" end * dates as amount, '系统生成' as maketype from (select a.bcode, sum(vacationDates) as dates ");
			cutPaymentSql.append(searchAllSalaryPriceSql);
			cutPaymentSql.append(" from (select count(1) as vacationDates, bcode from vacationDetail where vacationday between '");
			cutPaymentSql.append(startDateRawValue);
			cutPaymentSql.append("' and '");
			cutPaymentSql.append(endDateRawValue);
			cutPaymentSql.append("' and code = '");
			cutPaymentSql.append(holidayCode);
			cutPaymentSql.append("' group by bcode union all select sum(period)*1.0/8 as times, bcode from hr_Attendance_ot where useDate between '");
			cutPaymentSql.append(startDateRawValue);
			cutPaymentSql.append("' and '");
			cutPaymentSql.append(endDateRawValue);
			cutPaymentSql.append("' and holidayType = '");
			cutPaymentSql.append(holidayCode);
			cutPaymentSql.append("' group by bcode) a group by bcode) as detail");
		} else {
			cutPaymentSql.append(" end * dates as amount, '系统生成' as maketype from (select bcode, count(1) as dates ");
			cutPaymentSql.append(searchAllSalaryPriceSql);
			cutPaymentSql.append(" from vacationDetail a where vacationDay between '");
			cutPaymentSql.append(startDateRawValue);
			cutPaymentSql.append("' and '");
			cutPaymentSql.append(endDateRawValue);
			cutPaymentSql.append("' and code = '");
			cutPaymentSql.append(holidayCode);
			cutPaymentSql.append("' group by bcode) as eachVacationDates");
		}
		
		return cutPaymentSql.toString();
	}
	
	String searchAllSalaryPriceSql = "";
	
	/**
	 * 构建查询薪金项目的金额的SQL，用于最终的生成扣款中使用这个作为子查询来计算扣款
	 */
	private void addSalaryItemToMap() {
		String sql = "select distinct hr_salary_item.code,hr_salary_item.desc_cn from bcode_Allowance, hr_salary_item where  no_ = code union select distinct b.code, b.desc_cn from dbo.FixedExtPloy a, hr_salary_item b where a.code = b.code";
		final GreetingServiceAsync greetingService = GWT
				.create(com.base.myproject.client.tools.GreetingService.class);
		greetingService.getDataSet(sql, new AsyncCallback<DataSet>() {
			@Override
			public void onFailure(Throwable caught) {
			}

			@Override
			public void onSuccess(DataSet result) {
				for (int i=0; i<result.getRowCount(); i++) {
					searchAllSalaryPriceSql += ",(select isnull(sum(amount),0) from (" +
							"select top 1 hr_salary_item.code,amount from bcode_Allowance, hr_salary_item where  no_ = code " +
							"and code = '" + result.getValue(i, "code") + "' and bcode = a.bcode order by startdate desc union " +
							"select b.code, sum(amount) as amount from dbo.FixedExtPloy a, hr_salary_item b where a.code = b.code " +
							"and a.code = '" + result.getValue(i, "code") + "' group by b.code) as a) as " + result.getValue(i, "code");
				}
			}
		});
	}
	
	public static int days(int year, int month) {
		int days = 0;
		if (month != 2) {
			switch (month) {
			case 1:
			case 3:
			case 5:
			case 7:
			case 8:
			case 10:
			case 12:
				days = 31;
				break;
			case 4:
			case 6:
			case 9:
			case 11:
				days = 30;
			}
		} else {
			if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0)
				days = 29;
			else
				days = 28;
		}
		return days;
	}
	
	private boolean commandSql(String sql) {
		List<String> sqlList = new ArrayList<String>();
		sqlList.add(sql);
		return commandSql(sqlList);
	}
	
	private boolean commandSql(List<String> sqlList) {
		CommandSyncsql csql = new CommandSyncsql();// 执行sql命令
		csql.getV().addAll(sqlList);
		if (csql.getV().size() <= 0) {
			return false;
		} else {
			CommandSyncContainer list = new CommandSyncContainer();// 可以添加的命令
			list.add(csql);

			GreetingServiceAsync greetingService = GWT.create(GreetingService.class);
			greetingService.SendCommandSync(list,new AsyncCallback<CommandSyncReturnObject>() {
				@Override
				public void onFailure(Throwable caught) {
					MessageBox.alert("错误", "网络连接失败", null);
				}

				@Override
				public void onSuccess(CommandSyncReturnObject result) {
					if (result.isB()) {
						Info.display("提示信息", "生成数据成功");
						String refreshSql = "select * from hr_salary_ext where code = 'D14' and convert(varchar(10), adddate, 120) = '" + happenDateRawValue + "'";
						store.getStoreinfo().setSql(refreshSql);
						store.reload();
					} else {
						MessageBox.alert("错误", "错误，错误代码"+ result.getMessage(), null);
					}
				}
			});
		}
		return true;
	}
}